# backend/app/api/api_auth.py

from datetime import datetime, timedelta, timezone
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session

from app.auth.jwt import (
    create_access_token,
    create_refresh_token,
    get_current_active_user
)

from app.utils.password import hash_password, verify_password

from app.db.db_handler import get_db
from app.db.db_models import User

from app.api.api_model import UserRegister,ErrorResponse,SuccessResponse
from app.db.db_auth import DBAuth

from app.utils.logger import get_logger

logger = get_logger()

router = APIRouter(
    prefix="/auth",
    tags=["Authentication"],
)

db_dict = dict()

@router.post("/register", summary="注册新用户")
async def register(user: UserRegister, db: Session = Depends(get_db)):
    """用户注册接口"""
    db_auth = DBAuth(db)
    existing_user = db_auth.get_user(user.username)
    if existing_user:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="用户名已被注册"
        )
    # 创建新用户
    try:
        # new_user = User(
        #     username=user.username,
        #     hashed_password=hash_password(user.password)
        # )
        # db.add(new_user)
        # db.commit()
        # db.refresh(new_user)
        db_auth.create_user(user.username, hash_password(user.password))
    except Exception as e:
        logger.error(f"注册失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="注册失败"
        )
    
    return SuccessResponse(data={"message": "注册成功"})

@router.post("/login", summary="用户登录获取令牌")
async def login(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):
    """用户登录接口"""
    db_auth = DBAuth(db)
    user = db_auth.get_user(form_data.username)
    if not user or not verify_password(form_data.password, user.hashed_password):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="用户名或密码错误"
        )
    
    access_token = create_access_token({"sub": user.username})
    refresh_token = create_refresh_token({"sub": user.username})
    
    # 保存令牌到数据库
    db_auth.save_tokens(
        user_id=user.id,
        access_token=access_token,
        refresh_token=refresh_token,
        access_expires=datetime.now(timezone.utc) + timedelta(minutes=30),
        refresh_expires=datetime.now(timezone.utc) + timedelta(days=7)
    )
    
    return SuccessResponse(data={
            "access_token": access_token,
            "refresh_token": refresh_token,
        "token_type": "bearer"
    })

@router.post("/logout", summary="注销登录")
async def logout(current_user: User = Depends(get_current_active_user), db: Session = Depends(get_db)):
    """注销登录接口，撤销所有令牌"""
    db_auth = DBAuth(db)
    db_auth.revoke_all_tokens(current_user.id)
    return SuccessResponse(data={"message": "所有设备已注销"})

@router.post("/refresh-token", summary="刷新访问令牌")
async def refresh_token(refresh_token: str, db: Session = Depends(get_db)):
    """刷新访问令牌接口"""
    db_auth = DBAuth(db)
    user = db_auth.verify_refresh_token(refresh_token)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="无效的刷新令牌"
        )
    
    new_access_token = create_access_token({"sub": user.username})
    new_refresh_token = create_refresh_token({"sub": user.username})
    
    db_auth.save_tokens(
        user_id=user.id,
        access_token=new_access_token,
        refresh_token=new_refresh_token,
        access_expires=datetime.now(timezone.utc) + timedelta(minutes=30),
        refresh_expires=datetime.now(timezone.utc) + timedelta(days=7)
    )
    
    return SuccessResponse(data={
            "access_token": new_access_token,
            "refresh_token": new_refresh_token,
            "token_type": "bearer"
        })

@router.post("/reset-password", summary="重置密码")
async def reset_password(username: str, password: str, db: Session = Depends(get_db)):
    """重置密码接口"""
    db_auth = DBAuth(db)
    db_auth.reset_password(username, password)
    return SuccessResponse(data={"message": "密码已重置"})